home *** CD-ROM | disk | FTP | other *** search
-
- /** Read8SVX.c **********************************************************
- *
- * Read a sound sample from an IFF file. 21Jan85
- *
- * By Steve Hayes, Electronic Arts.
- * This software is in the public domain.
- *
- * Linkage:
- * LStartup.obj,Read8SVX.o,dunpack.o,iffr.o LIBRARY LC.lib,Amiga.lib
- *
- ************************************************************************/
-
- #include "exec/types.h"
- #include "exec/exec.h"
- #include "libraries/dos.h"
- #include "iff/8svx.h"
-
- /* Message strings for IFFP codes. */
- char MsgOkay[] = { "(IFF_OKAY) No FORM 8SVX in the file." };
- char MsgEndMark[] = { "(END_MARK) How did you get this message?" };
- char MsgDone[] = { "(IFF_DONE) All done."};
- char MsgDos[] = { "(DOS_ERROR) The DOS returned an error." };
- char MsgNot[] = { "(NOT_IFF) Not an IFF file." };
- char MsgNoFile[] = { "(NO_FILE) No such file found." };
- char MsgClientError[] = { "(CLIENT_ERROR) Read8SVX bug or insufficient RAM."};
- char MsgForm[] = { "(BAD_FORM) A malformed FORM 8SVX." };
- char MsgShort[] = { "(SHORT_CHUNK) A malformed FORM 8SVX." };
- char MsgBad[] = { "(BAD_IFF) A mangled IFF file." };
-
- /* THESE MUST APPEAR IN RIGHT ORDER!! */
- char *IFFPMessages[-LAST_ERROR+1] = {
- /*IFF_OKAY*/ MsgOkay,
- /*END_MARK*/ MsgEndMark,
- /*IFF_DONE*/ MsgDone,
- /*DOS_ERROR*/ MsgDos,
- /*NOT_IFF*/ MsgNot,
- /*NO_FILE*/ MsgNoFile,
- /*CLIENT_ERROR*/ MsgClientError,
- /*BAD_FORM*/ MsgForm,
- /*SHORT_CHUNK*/ MsgShort,
- /*BAD_IFF*/ MsgBad
- };
-
- typedef struct {
- ClientFrame clientFrame;
- UBYTE foundVHDR;
- UBYTE pad1;
- Voice8Header sampHdr;
- } SVXFrame;
-
-
- /* NOTE: For a simple version of this program, set Fancy to 0.
- * That'll compile a program that skips all LISTs and PROPs in the input
- * file. It will look in CATs for FORMs 8SVX. That's suitable for most uses.
- *
- * For a fancy version that handles LISTs and PROPs, set Fancy to 1.
- */
-
- #define Fancy 1
-
- BYTE *buf;
- int szBuf;
-
- /** DoSomethingWithSample() **********************************************
- *
- * Interface to Amiga sound driver.
- *
- *************************************************************************/
- DoSomethingWithSample(sampHdr) Voice8Header *sampHdr; {
- BYTE *t;
- printf("\noneShotHiSamples=%ld", sampHdr->oneShotHiSamples);
- printf("\nrepeatHiSamples=%ld", sampHdr->repeatHiSamples);
- printf("\nsamplesPerHiCycle=%ld", sampHdr->samplesPerHiCycle);
- printf("\nsamplesPerSec=%ld", sampHdr->samplesPerSec);
- printf("\nctOctave=%ld", sampHdr->ctOctave);
- printf("\nsCompression=%ld", sampHdr->sCompression);
- printf("\nvolume=0x%lx", sampHdr->volume);
- /* Decompress, if needed. */
- if (sampHdr->sCompression) {
- t = (BYTE *)AllocMem(szBuf<<1, MEMF_CHIP);
- DUnpack(buf, szBuf, t);
- FreeMem(buf, szBuf);
- buf = t;
- szBuf <<= 1;
- };
- printf("\nData = %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld",
- buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
- printf("\n %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld ...\n",
- buf[8+0],buf[8+1],buf[8+2],buf[8+3],buf[8+4],buf[8+5],
- buf[8+6],buf[8+ 7]);
- }
-
- /** ReadBODY() ***********************************************************
- *
- * Read a BODY into RAM.
- *
- *************************************************************************/
- IFFP ReadBODY(context) GroupContext *context; {
- IFFP iffp;
-
- szBuf = ChunkMoreBytes(context);
- buf = (BYTE *)AllocMem(szBuf, MEMF_CHIP);
- if (buf == NULL)
- iffp = CLIENT_ERROR;
- else
- iffp = IFFReadBytes(context, (BYTE *)buf, szBuf);
- CheckIFFP();
- }
-
- /** GetFo8SVX() **********************************************************
- *
- * Called via ReadSample to handle every FORM encountered in an IFF file.
- * Reads FORMs 8SVX and skips all others.
- * Inside a FORM 8SVX, it reads BODY. It complains if it
- * doesn't find an VHDR before the BODY.
- *
- * [TBD] We could read and print out any NAME and "(c) " chunks.
- *
- *************************************************************************/
- IFFP GetFo8SVX(parent) GroupContext *parent; {
- /*compilerBug register*/ IFFP iffp;
- GroupContext formContext;
- SVXFrame smusFrame; /* only used for non-clientFrame fields.*/
-
- if (parent->subtype != ID_8SVX)
- return(IFF_OKAY); /* just continue scaning the file */
-
- smusFrame = *(SVXFrame *)parent->clientFrame;
- iffp = OpenRGroup(parent, &formContext);
- CheckIFFP();
-
- do switch (iffp = GetFChunkHdr(&formContext)) {
- case ID_VHDR: {
- smusFrame.foundVHDR = TRUE;
- iffp = GetVHDR(&formContext, &smusFrame.sampHdr);
- break; }
- case ID_BODY: {
- if (!smusFrame.foundVHDR)
- iffp = BAD_FORM; /* Need an VHDR chunk first! */
- else iffp = ReadBODY(&formContext);
- break; }
- case END_MARK: {
- if (!smusFrame.foundVHDR)
- iffp = BAD_FORM;
- else
- iffp = IFF_DONE;
- break; }
- } while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
- * subroutine returned IFF_OKAY (no errors).*/
-
- if (iffp != IFF_DONE) return(iffp);
-
- /* If we get this far, there were no errors. */
- CloseRGroup(&formContext);
- DoSomethingWithSample(&smusFrame.sampHdr);
- FreeMem(buf, szBuf);
- return(iffp);
- }
-
- /** Notes on extending GetFo8SVX ****************************************
- *
- * To read more kinds of chunks, just add clauses to the switch statement.
- * To read more kinds of property chunks (like NAME) add clauses to
- * the switch statement in GetPr8SVX, too.
- *
- ************************************************************************/
-
- /** GetPr8SVX() *********************************************************
- *
- * Called via ReadSample to handle every PROP encountered in an IFF file.
- * Reads PROPs 8SVX and skips all others.
- *
- *************************************************************************/
- #if Fancy
- IFFP GetPr8SVX(parent) GroupContext *parent; {
- /*compilerBug register*/ IFFP iffp;
- GroupContext propContext;
- SVXFrame *svxFrame = (SVXFrame *)parent->clientFrame; /* Subclass */
-
- if (parent->subtype != ID_8SVX)
- return(IFF_OKAY); /* just continue scaning the file */
-
- iffp = OpenRGroup(parent, &propContext);
- CheckIFFP();
-
- do switch (iffp = GetPChunkHdr(&propContext)) {
- case ID_VHDR: {
- svxFrame->foundVHDR = TRUE;
- iffp = GetVHDR(&propContext, &svxFrame->sampHdr);
- break; }
- } while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
- * subroutine returned IFF_OKAY (no errors).*/
-
- CloseRGroup(&propContext);
- return(iffp == END_MARK ? IFF_OKAY : iffp);
- }
- #endif
-
- /** GetLi8SVX() **********************************************************
- *
- * Called via ReadSample to handle every LIST encountered in an IFF file.
- *
- *************************************************************************/
- #if Fancy
- IFFP GetLi8SVX(parent) GroupContext *parent; {
- SVXFrame newFrame; /* allocate a new Frame */
-
- newFrame = *(SVXFrame *)parent->clientFrame; /* copy parent frame */
-
- return( ReadIList(parent, (ClientFrame *)&newFrame) );
- }
- #endif
-
- /** ReadSample() **********************************************************
- *
- * Read IFF 8SVX, given a file handle open for reading.
- *
- *************************************************************************/
- IFFP ReadSample(file) LONG file; {
- SVXFrame sFrame; /* Top level "client frame".*/
- IFFP iffp = IFF_OKAY;
-
- #if Fancy
- sFrame.clientFrame.getList = GetLi8SVX;
- sFrame.clientFrame.getProp = GetPr8SVX;
- #else
- sFrame.clientFrame.getList = SkipGroup;
- sFrame.clientFrame.getProp = SkipGroup;
- #endif
- sFrame.clientFrame.getForm = GetFo8SVX;
- sFrame.clientFrame.getCat = ReadICat ;
-
- /* Initialize the top-level client frame's property settings to the
- * program-wide defaults. This example just records that we haven't read
- * any VHDR properties yet.
- * If you want to read another property, init it's fields in sFrame. */
- sFrame.foundVHDR = FALSE;
- sFrame.pad1 = 0;
-
- iffp = ReadIFF(file, (ClientFrame *)&sFrame);
-
- return(iffp);
- }
-
- /** main0() **************************************************************/
- void main0(filename) char *filename; {
- LONG file;
- IFFP iffp = NO_FILE;
- file = Open(filename, MODE_OLDFILE);
- if (file)
- iffp = ReadSample(file);
- Close(file);
- printf(" %s\n", IFFPMessages[-iffp]);
- }
-
- /** main() ***************************************************************/
- void main(argc, argv) int argc; char **argv; {
- printf("Reading file '%s' ...", argv[1]);
- if (argc < 2)
- printf("\nfilename required\n");
- else
- main0(argv[1]);
- }
-
-